﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SortGuid.Tool.Comb.Strategy;

namespace SortGuid.Tool.Comb
{
    public abstract class BaseCombProvider : ICombProvider
    {
        protected ICombDateTimeStrategy _dateTimeStrategy;

        private TimestampProvider _timestampProvider = DefaultTimestampProvider;

        public TimestampProvider TimestampProvider
        {
            get { return _timestampProvider; }
            private set { _timestampProvider = value; }
        }

        private GuidProvider _guidProvider = Guid.NewGuid;

        public GuidProvider GuidProvider
        {
            get { return _guidProvider; }
            private set { _guidProvider = value; }
        }

        public BaseCombProvider(ICombDateTimeStrategy dateTimeStrategy, TimestampProvider customTimestampProvider = null, GuidProvider customGuidProvider = null)
        {
            if (dateTimeStrategy.NumDateBytes != 4 && dateTimeStrategy.NumDateBytes != 6)
            {
                throw new NotSupportedException("ICombDateTimeStrategy is limited to either 4 or 6 bytes.");
            }

            _dateTimeStrategy = dateTimeStrategy;
            TimestampProvider = customTimestampProvider ?? new TimestampProvider(DefaultTimestampProvider);
            GuidProvider = customGuidProvider ?? new GuidProvider(Guid.NewGuid);
        }

        public abstract DateTime GetTimestamp(Guid comb);

        public Guid Create()
        {
            return Create(GuidProvider(), TimestampProvider());
        }

        public Guid Create(Guid value)
        {
            return Create(value, TimestampProvider());
        }

        public Guid Create(DateTime timestamp)
        {
            return Create(GuidProvider(), timestamp);
        }

        public abstract Guid Create(Guid value, DateTime timestamp);

        protected static DateTime DefaultTimestampProvider()
        {
            return DateTime.UtcNow;
        }
    }
}
